package RPC.rpc04;

import RPC.common.IUserService;
import RPC.common.User;
import net.sf.cglib.proxy.InvocationHandler;
import net.sf.cglib.proxy.Proxy;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.Socket;

/**
 * @Title 解决了方法增加的问题
 * @Author zhengqiang.tan
 * @Date 11/14/22 10:44 PM
 */
public class Stub {

    public static IUserService getStub() {

        /**
         * p1: 代理类的类加载器
         * p2: 代理类实现了哪些接口
         * p3: handler
         */
        Object o = Proxy.newProxyInstance(IUserService.class.getClassLoader(), new Class[]{IUserService.class}, new InvocationHandler() {
            /**
             *
             * @param proxy 代理对象
             * @param method 所要调用的方法
             * @param args 所携带的参数
             * @return
             * @throws Throwable
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Socket s = new Socket("127.0.0.1", 8888);
                ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());

                // 传输给服务器 方法名 方法类型 参数
                String methodName = method.getName();
                Class<?>[] parameterTypes = method.getParameterTypes();
                oos.writeUTF(methodName);
                oos.writeObject(parameterTypes);
                oos.writeObject(args);
                oos.flush();


                DataInputStream dis = new DataInputStream(s.getInputStream());
                int id = dis.readInt();

                String name = dis.readUTF();
                User user = new User(id, name);

                oos.close();
                s.close();

                return user;
            }
        });

        System.out.println(o.getClass().getName());
        System.out.println(o.getClass().getInterfaces()[0]);
        return (IUserService) o;
    }
}
